package com.cyx.gametool.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import com.cyx.gametool.excel.ExcelColumnTitle;
import com.cyx.gametool.excel.ExcelTableData;
import com.squareup.javapoet.*;
import javafx.scene.control.CheckBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import lombok.Getter;

import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ExcelToJavaController extends AbsBaseController {

    // 类名前缀
    public TextField classPrefix;
    // 类名后缀
    public TextField classSuffix;
    // 保存路径
    public TextField fileSavePath;
    // 包路径
    public TextField packagePath;
    // 是否启用驼峰式命名
    public CheckBox isUpDown;
    public RadioButton getMethod;
    // 启用get方法或者lombok注解
    public ToggleGroup getOrLombok;
    public RadioButton lombokMethod;

    /**
     * 使用javapoet生成java类
     *
     * @param excelTableData excel表格数据
     */
    public void excelToJavaClass(ExcelTableData excelTableData) throws IOException {
        String sheetName = excelTableData.getSheetName();
        // 文件名不含文件格式
        String prefix = FileNameUtil.getPrefix(excelTableData.getSourceFile());

        List<ExcelColumnTitle> excelColumnTitles = excelTableData.getExcelColumnTitles();
        if (CollUtil.isEmpty(excelColumnTitles)) {
            return;
        }
        // 是否启用lombok注解
        boolean isLombok = getOrLombok.getSelectedToggle().equals(lombokMethod);
        // 创建字段
        List<FieldSpec> fields = new ArrayList<>();
        // 创建字段get方法
        List<MethodSpec> methods = new ArrayList<>();
        for (ExcelColumnTitle excelColumnTitle : excelColumnTitles) {
            Class<?> javaType = excelColumnTitle.getFieldType().getJavaType();
            String fieldName = excelColumnTitle.getFieldName();
            fields.add(
                    FieldSpec.builder(
                                    javaType,
                                    fieldName,
                                    Modifier.PUBLIC
                            )
                            .build()
            );
            if (!isLombok) {
                String methodName = "get" + StrUtil.upperFirst(fieldName);
                methods.add(
                        MethodSpec.methodBuilder(methodName)
                                .addModifiers(Modifier.PUBLIC).
                                returns(TypeName.get(javaType))
                                .addStatement("return this.$N", fieldName)
                                .build()
                );
            }
        }
        // 创建类
        TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(getClassName(sheetName))
                .addModifiers(Modifier.PUBLIC)// 修饰符
                .addJavadoc(prefix + "\n\n")   // 类注释
                .addJavadoc("@Author $L\n", "cyx")   // 注释中的时间和作者
                .addJavadoc("@Date $L\n", DateUtil.now())   // 注释中的时间和作者
                .addFields(fields);
        if (isLombok) {
            typeBuilder.addAnnotation(Getter.class);
        } else {
            typeBuilder.addMethods(methods);
        }
        // 创建类
        TypeSpec typeSpec = typeBuilder.build();

        // 创建文件  包路径，类
        JavaFile javaFile = JavaFile.builder(packagePath.getText(), typeSpec)
                .build();

        // 控制台输出
        javaFile.writeTo(System.out);

        File outputDir = new File(fileSavePath.getText()); // 指定输出目录
        javaFile.writeTo(outputDir);

    }

    /**
     * 获取类名
     *
     * @param sheetName
     * @return
     */
    private String getClassName(String sheetName) {
        String className = classPrefix.getText() + sheetName + classSuffix.getText();
        if (isUpDown.isSelected()) {
            className = StrUtil.toCamelCase(className);
        }
        return StrUtil.upperFirst(className);
    }
}
